﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Yxinmt.Interface;
using Yxinmt.Utility;

namespace Yxinmt.Controls
{
    public class Popup : BaseControl, IControl
    {
        private System.Windows.Controls.Primitives.Popup _Popup { get; set; }

        public Popup(Dictionary<string, object> property, IComponent component)
        {
            Property = property;
            _Component = component;

            _Popup = new System.Windows.Controls.Primitives.Popup();
            this.Element = _Popup;

            InitSet();
            this.SetProperty();
            this.SetControlProperty(false, false);


            _Window.PopupList.Add(this);
        }

        public override void Add(System.Windows.FrameworkElement control)
        {
            _Popup.Child = control;
        }

        public void Show()
        {
            Task.Run(() =>
            {
                Thread.Sleep(100);
                this._Window.Window.Dispatcher.Invoke(() =>
                {
                    _Popup.IsOpen = true;
                });
            });
        }

        public void Hide()
        {
            _Popup.IsOpen = false;
        }

        public bool IsOpen
        {
            get { bool blOpen = false; this._Window.Window.Dispatcher.Invoke(() => blOpen = _Popup.IsOpen); return blOpen; }
        }

        private void SetProperty()
        {
            SetDefaultValue("AllowsTransparency", true);
            SetDefaultValue("Placement", "Custom");
            SetDefaultValue("IsOpen", false);
            SetDefaultValue("PopupAnimation", "Fade");
            SetDefaultValue("StaysOpen", true);

            _IsMove = Property.GetValue<bool>("IsMove");
        }

        bool _IsMove { get; set; }

        public void SetPlacementTarget(System.Windows.FrameworkElement element)
        {
            _Popup.PlacementTarget = element;
        }

        public void SetOffset(double x, double y)
        {
            if (x > 0) _Popup.HorizontalOffset = x;
            if (y > 0) _Popup.VerticalOffset = y;
        }

        protected override void SetProperty(string name, object value)
        {
            System.Windows.Controls.Primitives.Popup c = _Popup;
            switch (name)
            {
                case "Name": c.Name = string.Concat("popup_", (string)value); break;
                case "Height": c.Height = Convert.ToDouble(value); break;
                case "Width": c.Width = Convert.ToDouble(value); break;
                case "Dock": System.Windows.Controls.DockPanel.SetDock(c, this.GetDock((string)value)); break;
                case "AllowsTransparency": c.AllowsTransparency = (bool)value; break;
                case "IsOpen": c.IsOpen = (bool)value; break;
                case "StaysOpen": c.StaysOpen = (bool)value; break;
                case "ControlAlign": SetControlAlign((string)value); break;
                case "Visible": SetVisible((bool)value); break;
                case "GridRowColumn": SetGridRowColumn((string)value); break;
                case "BackImageUrl": SetBackgroundImage((string)value); break;
                case "ZIndex": SetZIndex((int)value); break;
                case "Placement": c.Placement = GetPlacement((string)value); break;
                case "Left": c.HorizontalOffset = Convert.ToDouble(value); break;
                case "Top": c.VerticalOffset = Convert.ToDouble(value); break;
                case "PopupAnimation": c.PopupAnimation = GetPopupAnimation((string)value); break;
            }
        }

        private System.Windows.Controls.Primitives.PopupAnimation GetPopupAnimation(string value)
        {
            switch (value)
            {
                case "Fade": return System.Windows.Controls.Primitives.PopupAnimation.Fade;
                case "Scroll": return System.Windows.Controls.Primitives.PopupAnimation.Scroll;
                case "Slide": return System.Windows.Controls.Primitives.PopupAnimation.Slide;
                default: return System.Windows.Controls.Primitives.PopupAnimation.None;
            }
        }

        private System.Windows.Controls.Primitives.PlacementMode GetPlacement(string value)
        {
            switch (value)
            {
                case "Absolute": return System.Windows.Controls.Primitives.PlacementMode.Absolute;
                case "AbsolutePoint": return System.Windows.Controls.Primitives.PlacementMode.AbsolutePoint;
                case "Bottom": return System.Windows.Controls.Primitives.PlacementMode.Bottom;
                case "Center": return System.Windows.Controls.Primitives.PlacementMode.Center;
                case "Custom": return System.Windows.Controls.Primitives.PlacementMode.Custom;
                case "Left": return System.Windows.Controls.Primitives.PlacementMode.Left;
                case "Mouse": return System.Windows.Controls.Primitives.PlacementMode.Mouse;
                case "MousePoint": return System.Windows.Controls.Primitives.PlacementMode.MousePoint;
                case "Relative": return System.Windows.Controls.Primitives.PlacementMode.Relative;
                case "RelativePoint": return System.Windows.Controls.Primitives.PlacementMode.RelativePoint;
                case "Right": return System.Windows.Controls.Primitives.PlacementMode.Right;
                default: return System.Windows.Controls.Primitives.PlacementMode.Top;
            }
        }

        public override void EventLoad()
        {
            base.EventLoad();

            if (_IsMove)
            {
                _Popup.MouseLeftButtonDown += _Popup_MouseLeftButtonDown;
                _Popup.MouseMove += _Popup_MouseMove;
                _Popup.MouseUp += _Popup_MouseUp;
            }
        }

        private void _Popup_MouseMove(object sender, System.Windows.Input.MouseEventArgs e)
        {
            if (e.LeftButton == System.Windows.Input.MouseButtonState.Pressed)
            {
                _IsMouseMove = true;

                Utility.MouseHook.DropMove();
                var p2 = Utility.MouseHook.GetCursorPoint();
                Utility.Win32Api.Mouse_Up(p2.X, p2.Y);
            }
        }

        bool _IsMouseMove { get; set; }

        public Action OnClick { get; set; }

        private void _Popup_MouseUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            if (_IsLeftDown && !_IsMouseMove)
            {
                if (OnClick != null) OnClick();
            }
            _IsMouseMove = false;
        }

        bool _IsLeftDown { get; set; }

        private void _Popup_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            _IsLeftDown = true;
        }
    }
}
